package com.volley.help;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Map;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;

public class LruMemoryCache extends LruCache<String, Bitmap> {

	// 弱引用二级缓存
	private final Map<String, Reference<Bitmap>> softMap = new HashMap<String, Reference<Bitmap>>();

	public LruMemoryCache(int maxSize) {
		super(maxSize);
	}

	/**
	 * 检查二级缓存：如果有，移除；并覆盖主缓存value
	 */
	public Bitmap putBitmap(String key, Bitmap value) {
		Bitmap bitmap = null;
		synchronized (softMap) {
			Reference<Bitmap> reference = softMap.get(key);
			if (reference != null) {
				bitmap = reference.get();
			}
			// 如果二级缓存有值，删除，主内存保存最新的
			if (bitmap != null) {
				softMap.remove(key);
				if (!bitmap.isRecycled()) {
					bitmap.recycle();
					bitmap = null;
				}
			}
		}
		bitmap = super.put(key, value);
		return bitmap;
	}

	/**
	 * 先从软引用取图片，取不到直接从主内存取
	 */
	public Bitmap getBitmap(String key) {
		Bitmap bitmap = null;
		synchronized (softMap) {
			Reference<Bitmap> reference = softMap.get(key);
			if (reference != null) {
				bitmap = reference.get();
				if (bitmap == null) {
					softMap.remove(key);
				}
			}
		}
		bitmap = bitmap == null ? super.get(key) : bitmap;
		return bitmap;
	}

	public Bitmap removeBitmap(String key) {
		synchronized (softMap) {
			softMap.remove(key);
		}

		return super.remove(key);
	}

	/**
	 * 清空1级2级缓存
	 */
	public void clearAll() {
		evictAll();
		softMap.clear();
	}

	public void checkMemory() {
		System.out.println("#main size:" + size());
		System.out.println("#soft size:" + softMap.size());
	}

	/**
	 * 超出内存时此方法被调用，移除最早的图片
	 */
	@Override
	protected void entryRemoved(boolean evicted, String key, Bitmap oldValue,
			Bitmap newValue) {
		System.out.println("#entryRemoved");
		synchronized (softMap) {
			// 被删除的图片加入二级缓存
			if (oldValue != null && evicted) {
				softMap.put(key, createReference(oldValue));
			} else {
				if (!oldValue.isRecycled()) {
					oldValue.recycle();
					oldValue = null;
				}
			}
		}
	}

	protected Reference<Bitmap> createReference(Bitmap value) {
		return new WeakReference<Bitmap>(value);
	}
}
